package com.donica.wamstest.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.springframework.util.ResourceUtils;

import com.donica.wamstest.entity.FileDTO;
import com.donica.wamstest.entity.FileVO;

/**
 * SpringBoot上传文件工具类
 * 
 * @author chris
 * @date 2020-02-06
 */
public class FileHandleUtil {

	/** 绝对路径 **/
	private static String absolutePath = "";

	/** 静态目录 **/
	private static String staticDir = "static";

	/** 文件存放的目录 **/
	private static String fileDir = "/upload/";

	/**
	 * 上传单个文件 最后文件存放路径为：static/upload/image/test.jpg
	 * 文件访问路径为：http://127.0.0.1:8080/upload/image/test.jpg
	 * 该方法返回值为：/upload/image/test.jpg
	 * 
	 * @param inputStream 文件流
	 * @param path        文件路径，如：image/
	 * @param filename    文件名，如：test.jpg
	 * @return 成功：上传后的文件访问路径，失败返回：null
	 */
	public static String upload(InputStream inputStream, String path, String filename) {
		// 第一次会创建文件夹
		createDirIfNotExists();

		String resultPath = fileDir + path + filename;

		// 存文件
		File uploadFile = new File(absolutePath, staticDir + resultPath);
		try {
			FileUtils.copyInputStreamToFile(inputStream, uploadFile);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

		return resultPath;
	}

	/**
	 * 创建文件夹路径
	 */
	private static void createDirIfNotExists() {
		if (!absolutePath.isEmpty()) {
			return;
		}

		// 获取跟目录
		File file = null;
		try {
			file = new File(ResourceUtils.getURL("classpath:").getPath());
		} catch (FileNotFoundException e) {
			throw new RuntimeException("获取根目录失败，无法创建上传目录！");
		}
		if (!file.exists()) {
			file = new File("");
		}

		absolutePath = file.getAbsolutePath();

		File upload = new File(absolutePath, staticDir + fileDir);
		if (!upload.exists()) {
			upload.mkdirs();
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param path 文件访问的路径upload开始 如： /upload/image/test.jpg
	 * @return true 删除成功； false 删除失败
	 */
	public static boolean delete(String path) {
		File file = new File(absolutePath, staticDir + path);
		if (file.exists()) {
			return file.delete();
		}
		return false;
	}

	private static Long getFileCreateTime(File file) {
		try {
			Path path = Paths.get(file.getPath());
			BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class,
					LinkOption.NOFOLLOW_LINKS);
			BasicFileAttributes attr = basicview.readAttributes();
			return attr.creationTime().toMillis();
		} catch (Exception e) {
			e.printStackTrace();
			return file.lastModified();
		}
	}

	/**
	 * TODO:递归扫描指定文件夹下面的指定文件
	 * 
	 * @return ArrayList<Object>
	 * @author chris
	 * @date 2020-02-06
	 */
	public static ArrayList<FileVO> scanFilesWithRecursion(String folderPath) throws Exception {

		ArrayList<FileVO> scanFiles = new ArrayList<FileVO>();
		ArrayList<String> dirctorys = new ArrayList<String>();
		File directory = new File(folderPath);
		if (!directory.isDirectory()) {
			throw new Exception('"' + folderPath + '"'
					+ " input path is not a Directory , please input the right path of the Directory. ^_^...^_^");
		}
		if (directory.isDirectory()) {
			File[] filelist = directory.listFiles();
			for (int i = 0; i < filelist.length; i++) {
				/** 如果当前是文件夹，进入递归扫描文件夹 **/
				if (filelist[i].isDirectory()) {
					dirctorys.add(filelist[i].getAbsolutePath());
					/** 递归扫描下面的文件夹 **/
					scanFilesWithRecursion(filelist[i].getAbsolutePath());
				}
				/** 非文件夹 **/
				else {

					FileVO vo = new FileVO();
					vo.setName(filelist[i].getName());
					vo.setUri(filelist[i].getAbsolutePath());
					vo.setSize(filelist[i].length());

					long modify = filelist[i].lastModified();
					long create = getFileCreateTime(filelist[i]);
					vo.setCreate_time(new Timestamp(create));
					vo.setUpdate_time(new Timestamp(modify));
					vo.setExt(vo.getName().substring(vo.getName().lastIndexOf(".") + 1));
					scanFiles.add(vo);
				}
			}
		}
		return scanFiles;
	}

	public static void scanFilesWithRecursion(String folderPath, List<FileDTO> list) throws Exception {

		File directory = new File(folderPath);
		if (!directory.isDirectory()) {
			throw new Exception('"' + folderPath + '"'
					+ " input path is not a Directory , please input the right path of the Directory. ^_^...^_^");
		} else {

			File[] filelist = directory.listFiles();
			for (int i = 0; i < filelist.length; i++) {

				if (!filelist[i].isDirectory()) {
					FileDTO vo = new FileDTO();
					vo.setName(filelist[i].getName());
					vo.setUri(filelist[i].getAbsolutePath());
					vo.setSize(filelist[i].length());

					long modify = filelist[i].lastModified();
					long create = getFileCreateTime(filelist[i]);
					vo.setCreate_time(new Timestamp(create));
					vo.setUpdate_time(new Timestamp(modify));
					vo.setExt(vo.getName().substring(vo.getName().lastIndexOf(".") + 1));
					list.add(vo);
				}
			}
		}
	}

	public static void scanDirsWithRecursion(String folderPath, List<String> list) throws Exception {

		File directory = new File(folderPath);
		if (!directory.isDirectory()) {
			throw new Exception('"' + folderPath + '"'
					+ " input path is not a Directory , please input the right path of the Directory. ^_^...^_^");
		} else {
			File[] filelist = directory.listFiles();
			for (int i = 0; i < filelist.length; i++) {

				if (filelist[i].isDirectory()) {
					list.add(filelist[i].getName());
				}
			}
		}
	}

}